﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace JiravaNet.Web.UI.Fieldset {
	/// <summary>
	/// Class for fieldset control
	/// </summary>
	public class Fieldset {
		private readonly HtmlHelper _helper;

		/// <summary>
		/// ctor. s predanymi informacemi pro vygenerovani html prvku pro editaci zaznamu
		/// </summary>
		/// <param name="caption">nadpisek pro polozky</param>
		/// <param name="items">definice polozek</param>
		/// <param name="writer">writer pouzity k zapisu prvku</param>
		/// <param name="helper"><see cref="HtmlHelper"/> instance</param>
		public Fieldset(string caption, FieldsetBuilder items, TextWriter writer, HtmlHelper helper) {
			_helper = helper;
			Items = items;
			Caption = caption;
			Writer = writer;
		}

		/// <summary>
		/// Definice polozek
		/// </summary>
		protected FieldsetBuilder Items {
			get;
			set;
		}

		/// <summary>
		/// Writer pouzity k zapisu prvku
		/// </summary>
		protected TextWriter Writer {
			get;
			private set;
		}

		/// <summary>
		/// Zapise text na vystup
		/// </summary>
		/// <param name="text">text k zapsani na vystup</param>
		protected void RenderText(string text) {
			Writer.Write(text);
		}

		/// <summary>
		/// Zajisti vygenerovani prvku
		/// </summary>
		public virtual void Render() {

			RenderDataFormStart();
			RenderCaption();

			RenderItems();

			RenderDataFormEnd();
		}

		/// <summary>
		/// Nadpisek pro polozky
		/// </summary>
		private string Caption { get; set; }

		/// <summary>
		/// Vygenerovani jednotlivych polozek
		/// </summary>
		private void RenderItems() {

			bool isAlternate = false;
			foreach (var item in Items) {
				RenderStartItem(isAlternate);
				object value = null;
				if (item.Actions.Count > 0) {
					var sb = new StringBuilder(item.Actions.Count);
					foreach (var action in item.Actions) {
						sb.Append(action(_helper));
					}
					value = sb.ToString();
				} else {
					value = item.Value ?? string.Empty;
				}
				if (!string.IsNullOrEmpty(item.Header)) {
					RenderText(string.Format("<label for=\"{1}\">{0}</label><br />", HttpUtility.HtmlEncode(item.Header), item.Name));
				}
				RenderText(value.ToString());

				RenderEndItem();
				isAlternate = !isAlternate;
			}
		}

		/// <summary>
		/// Vygenerovani uvodni znacky pro polozku
		/// </summary>
		/// <param name="alternate">identifikuje, zda se jedna o alternativni polozku</param>
		private void RenderStartItem(bool alternate) {
			if (!alternate) {
				RenderText(string.Format("<p class=\"row\">"));
			} else {
				RenderText(string.Format("<p class=\"rowalt\">"));
			}
		}

		/// <summary>
		/// Vygenerovani koncove znacky pro polozku
		/// </summary>
		private void RenderEndItem() {
			RenderText(string.Format("</p>"));
		}

		/// <summary>
		/// Vygenerovani uvodni znacky
		/// </summary>
		private void RenderDataFormStart() {
			RenderText(string.Format("<fieldset>"));
		}

		/// <summary>
		/// Vygenerovani nadpisu polozek
		/// </summary>
		private void RenderCaption() {
			RenderText(string.Format("<caption>{0}</caption>", Caption));
		}

		/// <summary>
		/// Vygenerovani koncove znacky
		/// </summary>
		private void RenderDataFormEnd() {
			RenderText(string.Format("</fieldset>"));
		}

	}
}